<?php

declare(strict_types=1);

namespace App\Controller;

use App\Models\Agent;
use App\Models\PaymentOrder;
use App\Service\PaymentService;
use App\Service\WechatFactory;
use Carbon\Carbon;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpMessage\Exception\HttpException;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Psr\Log\LoggerInterface;
use Qbhy\HyperfAuth\AuthManager;

/**
 * @Controller(prefix="/api/h5/v2/payment")
 */
class PaymentController extends AbstractController
{
    /**
     * @var LoggerInterface
     */
    protected $logger;

    /**
     * @Inject()
     * @var WechatFactory
     */
    protected $wechatFactory;

    /**
     * @Inject()
     * @var AuthManager
     */
    protected $auth;

    /**
     * @Inject()
     * @var ValidatorFactoryInterface
     */
    protected $validationFactory;

    /**
     * @Inject()
     * @var PaymentService
     */
    protected $paymentService;

    public function __construct(LoggerFactory $loggerFactory)
    {
        $this->logger = $loggerFactory->get('log', 'default');
    }

    /**
     * 代理商充值
     * @PostMapping(path="agent-top-up")
     */
    public function topUp(RequestInterface $request)
    {
        $reqData = $this->validationFactory->make(
            $request->all(),
            [
                'amount' => 'required|integer|min:20101|top_up_mantissa_limit', // 单次最少充值 201 块钱, 末位数不能为 0 (top_up_mantissa_limit 自定义验证)
                'channel' => 'required|in:' . PaymentOrder::PAYMENT_CHANNEL_WECHAT,
            ],
            [
                'amount.required' => '缺失充值金额',
                'amount.integer' => '充值金额不合法(必须为数字类型)',
                'amount.min' => '充值金额不得少于201.01元',
                'channel.required' => '缺失支付渠道',
                'channel.in' => '支付渠道不存在',
            ]
        )->validated();

        /** @var Agent $user */
        $user = $this->auth->user();
        if (($wechat = $user->wechat()->first()) === null) {
            throw new HttpException(400, '当前用户微信信息获取失败');
        }
        // 先创建收银台订单
        $businessOrderId = PaymentOrder::ORDER_ID_PREFIX[PaymentOrder::ORDER_TYPE_TOP_UP] . Carbon::now()->format('YmdHisu') . random_int(0, 9); // 充值表的订单号
        [$paymentOrder, $channelOrder] = $this->paymentService->defray(array_merge(
            $reqData,
            [
                'body' => '账户余额充值',
                'out_trade_no' => $businessOrderId, // 业务订单号
                'trade_type' => 'JSAPI',
                'openid' => $wechat['openid'],
                // 通知地址根据业务订单前缀两位来统一处理
            ]
        ));

        $user->topUpOrder()->create([
            'order_id' => $businessOrderId,
            'payment_order_id' => $paymentOrder['order_id'], // 收银台订单号
            'amount' => $reqData['amount'],
            'payment_channel' => $reqData['channel']
        ]);

        return $this->response->json($this->wechatFactory->payment()->jssdk->sdkConfig($channelOrder['prepay_id']));
    }
}
